package com.sojson.config.shutdown;

import java.util.concurrent.TimeUnit;

import org.springframework.context.annotation.Configuration;

import com.sojson.util.SystemUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * 应用程序关闭后的操作配置类(在{@link org.springframework.beans.factory.DisposableBean}之前执行)</BR>
 * </BR>
 * 1.程序正常退出</BR>
 * 2.使用System.exit()</BR>
 * 3.终端使用Ctrl+C触发的中断</BR>
 * 4.系统关闭</BR>
 * 5.使用Kill pid命令干掉进程</BR>
 * 6.在使用kill -9 pid是不会JVM注册的钩子不会被调用</BR>
 * </BR>
 * 什么是Shutdown Hook</BR>
 * Shutdown hook是一个initialized but unstarted thread.当JVM开始执行shutdown sequence时</BR>
 * 会并发运行所有registered Shutdown Hook.这时,在Shutdown Hook这个线程里定义的操作便会开始执行</BR>
 * 需要注意的是,在Shutdown Hook里执行的操作应当是不太耗时的</BR>
 * 因为在用户注销或者操作系统关机导致的JVM shutdown的例子中,系统只会预留有限的时间给未完成的工作,超时之后还是会强制关闭</BR>
 *
 * @author liu
 * @date 2021-08-17
 */
@Slf4j
@Configuration
public class ShutdownConfig {

    {
        // 此任务是为了给Spring执行结束任务的时间,因为调用System.exit()的时候会强制中断程序,Spring还来不及调用结束任务
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            @SuppressWarnings("synthetic-access")
            public void run() {
                try {
                    SystemUtil.THREAD_SHUTDOWN_COUNT.await(60, TimeUnit.SECONDS);
                } catch (InterruptedException e) {
                    log.error(e.getMessage(), e);
                }
            }
        });
    }

}